package com.aliang.shopping.util.excel.listener;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.aliang.shopping.model.converter.NoticeConverter;
import com.aliang.shopping.model.dto.notice.NoticeImportDTO;
import com.aliang.shopping.model.po.Notice;
import com.aliang.shopping.service.NoticeService;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.util.ListUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
public class NoticeImportListener extends MyAnalysisEventListener<NoticeImportDTO> {

    // 有效条数
    private int validCount;

    // 无效条数
    private int invalidCount;

    // 导入返回信息
    StringBuilder msg = new StringBuilder();

    private final NoticeConverter noticeConverter;
    private final NoticeService noticeService;
    /**
     * 每隔100条存储数据库，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 100;
    private List<NoticeImportDTO> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

    public NoticeImportListener(NoticeConverter noticeConverter, NoticeService noticeService) {
        super();
        this.noticeConverter = noticeConverter;
        this.noticeService = noticeService;
    }

    @Override
    public void invoke(NoticeImportDTO noticeImportDTO, AnalysisContext analysisContext) {
        log.info("解析到一条用户数据:{}", JSONUtil.toJsonStr(noticeImportDTO));
        // 校验数据
        StringBuilder validationMsg = new StringBuilder();
        // 标题校验
        if (StrUtil.isBlank(noticeImportDTO.getTitle())) {
            validationMsg.append("标题为空。");
        }
        // 内容校验
        if (StrUtil.isBlank(noticeImportDTO.getContent())) {
            validationMsg.append("内容为空。");
        }
        // 接收端数字校验
        if (noticeImportDTO.getToNum() == null || noticeImportDTO.getToNum() < 0 || noticeImportDTO.getToNum() > 1) {
            validationMsg.append("接收端数字不合法。");
        }
        // 数据有效，累加有效条数
        if (validationMsg.length() <= 0) {
            validCount++;
            // 暂存至缓冲区
            cachedDataList.add(noticeImportDTO);
            //缓存区数据超过最大存储数量，存入数据
            if (cachedDataList.size() >= BATCH_COUNT) {
                saveData();
            }
        } else {
            invalidCount++;
            msg.append("第").append(validCount + invalidCount).append("行数据校验失败：").append(validationMsg).append("<br/>");
        }
    }


    /**
     * 所有数据解析完成会来调用
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        //最后的数据还要保存
        if (cachedDataList.size() > 0) {
            saveData();
        }
        log.info("所有数据解析完成！");
    }

    /**
     * 批量插入数据库操作
     */
    private void saveData() {
        //转换数据
        List<Notice> list = this.noticeConverter.toPoListByImportDTOList(cachedDataList);
        this.noticeService.saveBatch(list);
        // 清空数据
        cachedDataList.clear();
    }

    @Override
    public String getMsg() {
        // 总结信息
        return StrUtil.format("导入结束：成功{}条，失败{}条；<br/>{}", validCount, invalidCount, msg);
    }
}
